<template>
  <div class="vehicle-management">
    <div class="map-container" :style="{ width: isCollapsed ? '100%' : '75%' }">
      <div id="mapDiv" />

      <el-tooltip
        effect="dark"
        content="找不到我在哪？点一下就找到"
        placement="left"
      >
        <div
          class="position-icon"
          @click="handleFocusNow"
        >
          <svg-icon
            icon-class="position"
            class-name="position-icon__icon"
          />
        </div>
      </el-tooltip>

      <div
        class="operate"
        :style="{
          'border-radius': isCollapsed ? '15px 15px 0 0' : '15px 0 0 0'
        }"
      >
        <el-form :inline="true" :model="formHistory" class="demo-form-inline">
          <el-form-item label="查询车辆">
            <el-select
              v-model="id"
              placeholder="请选择需查询的车辆"
              @change="handleSelectVehicleChange"
            >
              <el-option
                v-for="item in vehiclesList"
                :key="item.id"
                :label="item.license_plate_number"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="查询时间">
            <el-date-picker
              v-model="formHistory.time"
              type="daterange"
              range-separator="至"
              :picker-options="pickerOptions"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              @change="handleTimeChange"
            />
            <el-button
              style="margin-left: 5px;"
              type="primary"
              :loading="loading"
              @click="queryHistory()"
            >
              查询
            </el-button>
          </el-form-item>
          <el-form-item v-if="historyData.length > 0" label="">
            <el-button-group style="margin-left: 5px;">
              <el-button type="success" round @click="start()">开始</el-button>
              <el-button type="warning" round :disabled="status != 1" @click="stop()">暂停</el-button>
              <el-button type="danger" round :disabled="status === 0" @click="finish()">停止</el-button>
            </el-button-group>
          </el-form-item>
          <el-form-item v-if="historyData.length > 0" label="总里程">
            {{ mileage }}km
          </el-form-item>
          <el-form-item v-if="historyData.length > 0" label="当前车速">
            {{ speed }}km/h
          </el-form-item>

        </el-form>
      </div>
    </div>
    <div v-show="!isCollapsed" class="stay-position">
      <div class="title">
        <h3>停留点信息</h3>
      </div>
      <div class="stay-position-list">

        <div
          v-for="(item, index) in stayPositionList"
          :key="index"
          class="stay-position-list__item"
          :class="{
            'active': currentStayPosition?.id === item?.id
          }"
          @click="handleChoiceStayPosition(item)"
        >
          <el-card
            shadow="hover"
          >
            <template #header>
              <div class="card-header">
                停留点{{ index + 1 >= 10 ? index + 1 : '0' + (index + 1) }}
              </div>
            </template>

            <el-descriptions :column="1" border>
              <el-descriptions-item label="停留地点">{{ item.addressParse }}</el-descriptions-item>
              <el-descriptions-item label="停留时长">{{ item.timeInterval }}</el-descriptions-item>
              <el-descriptions-item label="停留时间">
                {{ item.startTime }} ~ {{ item.endTime }}
              </el-descriptions-item>
            </el-descriptions>
          </el-card>
        </div>
      </div>
    </div>
    <div class="collapse-btn" @click="toggleCollapse">
      <i :class="isCollapsed ? 'el-icon-d-arrow-left' : 'el-icon-d-arrow-right'" />
    </div>
  </div>

</template>

<script>
import {
  getVehiclesList
} from '@/api/vehicleService'
import { stopTime, newLocation, history, address } from '@/api/gps'
const T = window.T
import dayjs from 'dayjs'
import { isArray } from 'lodash-es'
import vehicleGpsMixin from '@/views/vehicleService/js/vehicleGpsMixin'
import '@/assets/Tdt/D3SvgOverlay'
import '@/assets/Tdt/CarTrack'
export default {
  name: '',
  mixins: [vehicleGpsMixin],
  data() {
    return {
      status: 0,
      id: null,
      formHistory: {
        time: [],
        id: null
      },
      CarTrack: null,
      historyData: [],
      mileage: 0,
      dataLength: 0,
      speed: 0,
      loading: false,
      pickerOptions: {
        disabledDate(time) {
          const yesterday = new Date()
          yesterday.setHours(0, 0, 0, 0)
          yesterday.setDate(yesterday.getDate() - 1)
          return time.getTime() > yesterday.getTime()
        }
      },
      vehiclesList: [],
      isCollapsed: false,
      stayPositionList: [],
      currentStayPosition: null,
      animationFrameId: null,
      animating: false,
      currentVehicle: null,
      currentVehicleLastLocation: null, // 用于存储最新位置信息

      // 优化：倒计时相关变量
      isRefreshButtonDisabled: true, // 默认禁用，直到倒计时结束
      countdown: 5,
      countdownTimer: null
    }
  },
  watch: {
    stayPositionList: {
      handler(val) {
        if (val.length > 0) {
          this.isCollapsed = false
        } else {
          this.isCollapsed = true
        }
      },
      immediate: true
    }
  },
  created() {
    this.id = parseInt(this.$route.params.id)
    if (!this.defaultLonLat) {
      this.defaultLonLat = [116.40, 39.90]
    }

    const end = dayjs().subtract(1, 'day').endOf('day').toDate()
    const start = dayjs().subtract(7, 'day').startOf('day').toDate()
    this.formHistory.time = [start, end]
  },
  mounted() {
    this.initVehicleGpsHistoryData()
  },
  beforeDestroy() {
    // 组件销毁前清除定时器
    clearInterval(this.countdownTimer)
  },
  methods: {
    toggleCollapse() {
      this.isCollapsed = !this.isCollapsed
      if (this.map) {
        setTimeout(() => {
          this.map.checkResize()
        }, 300)
      }
    },

    // 优化：新的、不闪烁的错误处理逻辑
    handleRefreshError() {
      // 1. 重置倒计时状态
      clearInterval(this.countdownTimer)
      this.countdown = 5
      this.isRefreshButtonDisabled = true

      // 2. 立即弹出 Element UI 弹窗
      // 注意：这里使用 $alert 是因为您代码中有 this.$alert，
      // 但 $alert/$$confirm 的确认按钮文本是固定的，不能实时变化。
      // 我们在确认按钮回调中手动检查禁用状态。
      this.$alert('初始化定位数据异常，请尝试重新加载。', '数据错误 (400 Bad Request)', {
        confirmButtonText: '刷新页面内容',
        showCancelButton: true,
        type: 'error',
        closeOnClickModal: false,
        callback: action => {
          // 只有点击确认按钮才执行逻辑
          if (action === 'confirm') {
            if (this.isRefreshButtonDisabled) {
              this.$message.warning(`请等待 ${this.countdown} 秒后再次点击刷新。`)
              // 重新弹窗以阻止用户操作，但会再次导致闪烁！
              // 解决办法是让用户自行关闭弹窗，不重新弹窗。
              // 或者我们必须手动操作 DOM，这是唯一在不重构的情况下不闪烁的办法。

              // 考虑到避免闪烁是首要目标，我们不再重新弹窗，
              // 而是让用户自行关闭并等待。
              return
            } else {
              // 倒计时结束，执行刷新
              this.softRefresh()
            }
          }
          // 用户点击取消或关闭弹窗时，清除定时器
          clearInterval(this.countdownTimer)
          this.isRefreshButtonDisabled = true
          this.countdown = 5
        }
      }).catch(() => {
        // 捕获用户点击取消或关闭
        clearInterval(this.countdownTimer)
        this.isRefreshButtonDisabled = true
        this.countdown = 5
      })

      // 3. 启动倒计时，手动更新 DOM 上的按钮文本和禁用状态（这是最不推荐但最有效的无闪烁方案）
      const checkAndModifyButton = () => {
        const confirmButton = document.querySelector('.el-message-box__btns .el-button--primary')
        if (confirmButton) {
          if (this.countdown > 0) {
            confirmButton.disabled = true
            confirmButton.textContent = `刷新页面内容 (${this.countdown}s)`
          } else {
            confirmButton.disabled = false
            confirmButton.textContent = '刷新页面内容'
            clearInterval(this.countdownTimer)
            this.isRefreshButtonDisabled = false
          }
        }
      }

      // 启动倒计时
      this.countdownTimer = setInterval(() => {
        if (this.countdown > 0) {
          this.countdown--
          checkAndModifyButton()
        } else {
          clearInterval(this.countdownTimer)
          this.isRefreshButtonDisabled = false
          checkAndModifyButton() // 确保按钮状态和文本在倒计时为0时更新
        }
      }, 1000)

      // 首次运行时，立即检查并设置按钮初始状态
      this.$nextTick(() => {
        checkAndModifyButton()
      })
    },

    async initVehicleGpsHistoryData() {
      try {
        await this.getVehicleList()

        if (!this.id || !this.currentVehicle) {
          this.$message.error('URL中车辆ID无效，请返回列表重新选择。')
          this.initMap(this.defaultLonLat[0], this.defaultLonLat[1], 13)
          return
        }

        const res = await newLocation({ id: this.id })
        const car = res.data[0]

        if (!car) {
          this.$message.warning('当前车辆暂无最新定位数据，地图将使用默认中心点。')
          this.initMap(this.defaultLonLat[0], this.defaultLonLat[1], 13)
          if (this.formHistory.time && this.formHistory.time.length === 2) {
            this.queryHistory()
          }
          return
        }

        this.currentVehicleLastLocation = car
        this.initMap(car.lastLon, car.lastLat, 18)
        this.getVehiclesNowLocation(car)

        if (this.formHistory.time && this.formHistory.time.length === 2) {
          this.queryHistory()
        }
      } catch (error) {
        console.error('获取GPS最新位置失败：', error)

        if (error.response && error.response.status === 400) {
          // 调用新的、不闪烁的错误处理逻辑
          this.handleRefreshError()

          this.initMap(this.defaultLonLat[0], this.defaultLonLat[1], 13)
        } else {
          this.$message.error('车辆数据初始化失败，请检查网络。')
          this.initMap(this.defaultLonLat[0], this.defaultLonLat[1], 13)
        }
      }
    },
    initMap(lon, lat, zoom) {
      if (!this.map) {
        this.map = new T.Map('mapDiv', { projection: 'EPSG:900913' })
        const scale = new T.Control.Scale()
        const control = new T.Control.Zoom()
        this.map.addControl(control)
        this.map.addControl(scale)
      }
      this.map.centerAndZoom(new T.LngLat(lon, lat), zoom)
    },
    async queryHistory() {
      if (!isArray(this.formHistory.time) || this.formHistory.time.length !== 2) {
        this.$message.error('请选择正确的时间范围')
        return
      }

      if (!this.currentVehicle?.imei) {
        return this.$message.error('该车辆暂未绑定GPS设备，请绑定后尝试')
      }

      this.loading = true
      this.clearMapOverlays()

      const start = dayjs(this.formHistory.time[0]).format('YYYY-MM-DD HH:mm:ss')
      const end = dayjs(this.formHistory.time[1]).endOf('day').format('YYYY-MM-DD HH:mm:ss')

      try {
        const res = await history({ 'start': start, 'end': end, 'id': this.id })
        const stopres = await stopTime({ 'start': start, 'end': end, 'id': this.id })

        if (!res.data || res.data.length <= 0) {
          this.loading = false
          this.$message.error('当前暂无历史轨迹数据')
          return
        }

        this.stayPositionList = stopres.data?.records?.reverse() || []

        this.stayPositionList.forEach(element => {
          var marker = new T.Marker(new T.LngLat(element.lon, element.lat))
          marker.id = element.id
          this.map.addOverLay(marker)

          marker.addEventListener('click', () => {
            const windowInfo = this.createInfoWindow(element)
            marker.openInfoWindow(windowInfo)
          })

          element.marker = marker
        })

        this.historyData = res.data
        const arr = res.data.map(element => {
          return new T.LngLat(element.lon, element.lat)
        })
        var startMileage = res.data[0].mileage
        var endMileage = res.data[res.data.length - 1].mileage
        var mileage = endMileage - startMileage
        this.mileage = mileage
        this.dataLength = res.data.length

        this.map.setViewport(arr)
        this._CarTrack = new T.CarTrack(this.map, {
          interval: 5,
          speed: 1,
          dynamicLine: true,
          polylinestyle: { color: '#2C64A7', weight: 10, opacity: 0.9 },
          Datas: arr,
          passOneNode: this.passOneNode,
          carstyle: {
            iconUrl: 'https://obs-user-test.obs.cn-east-3.myhuaweicloud.com:443/pictures/test_1753672404_aImt0o3Jg7.png'
          }
        })
      } catch (error) {
        this.$message.error('历史轨迹查询失败，请检查时间或网络。')
        console.error('查询历史轨迹失败:', error)
      } finally {
        this.loading = false
      }
    },
    passOneNode(gps, index, len) {
      var p = index / len
      var i = this.dataLength * p
      this.index = Math.floor(i)
      this.speed = this.historyData[this.index].speed
      if (index === len) {
        this._CarTrack.stop()
        this.status = 0
      }
    },
    start() {
      this.status = 1
      this._CarTrack.start()
    },
    stop() {
      this.status = 2
      this._CarTrack.pause()
    },
    finish() {
      this.status = 0
      this._CarTrack.stop()
      this.speed = 0
    },

    async getVehicleList() {
      const res = await getVehiclesList({ 'gps': true })
      const { car, gps } = res.data
      const gpsMap = new Map(gps.map(item => [item.imei, item]))

      this.vehiclesList = car.map(item => {
        return {
          ...item,
          gps: gpsMap.get(item.imei) || {}
        }
      })
      this.currentVehicle = this.vehiclesList.find(item => item.id === this.id)
    },

    handleChoiceStayPosition(item) {
      if (item.id === this.currentStayPosition?.id) return

      if (this.animationFrameId) {
        this.cancelMarkerFlashing(this.currentStayPosition.marker)
      }
      this.currentStayPosition = item

      this.setCenterAndZoom(item.lon, item.lat, 18)
      this.startMarkerFlashing(item.marker)
    },

    setCenterAndZoom(lon, lat, zoom) {
      this.map.centerAndZoom(new T.LngLat(lon, lat), zoom)
    },

    // 清除地图上的所有动态覆盖物
    clearMapOverlays() {
      this._CarTrack?.clear()
      // 移除地图上的所有覆盖物
      this.map?.clearOverLays()

      this.historyData = []
      this.stayPositionList = []
      this.currentStayPosition = null
      this.status = 0
      this.speed = 0
      this.mileage = 0
    },

    softRefresh() {
      clearInterval(this.countdownTimer)
      this.countdown = 5
      this.isRefreshButtonDisabled = true
      this.clearMapOverlays()

      this.$nextTick(() => {
        this.initVehicleGpsHistoryData()
        this.$message.success('页面内容已重新加载！')
      })
    },

    startMarkerFlashing(marker) {
      let start = null
      const duration = 1000
      this.animating = true
      const animate = (timestamp) => {
        if (!this.animating || !marker) return
        if (!start) start = timestamp
        const elapsed = timestamp - start
        const progress = Math.min(elapsed / duration, 1)
        const opacity = (Math.sin(progress * Math.PI * 6) + 1) / 2

        marker.setOpacity(opacity)

        if (progress < 1) {
          this.animationFrameId = requestAnimationFrame(animate)
        } else {
          marker.setOpacity(1)
          this.animationFrameId = requestAnimationFrame(animate)
        }
      }

      this.animationFrameId = requestAnimationFrame(animate)
    },

    cancelMarkerFlashing(marker) {
      this.animating = false
      cancelAnimationFrame(this.animationFrameId)
      this.animationFrameId = null
      if (marker) marker.setOpacity(1)
    },

    createInfoWindow(stayPosition) {
      const infoWindow = new T.InfoWindow()
      const windowContent = `
        <b>停留时长：${stayPosition.timeInterval}</b><br/>
        <b>停留地点：${stayPosition.addressParse}</b><br/>
        <b>停留时间：${stayPosition.startTime}-${stayPosition.endTime}</b><br/>
      `
      infoWindow.setContent(windowContent)
      return infoWindow
    },

    async getVehiclesNowLocation(lastLocation) {
      this.currentVehicle = this.vehiclesList.find(item => item.id === this.id)
      this.currentVehicle.lastLocation = lastLocation
      const lon = this.currentVehicle.lastLocation.lastLon
      const lat = this.currentVehicle.lastLocation.lastLat
      const degree = this.currentVehicle.lastLocation.lastCourse || 0
      const addressres = await address({ 'lat': lat, 'lon': lon })
      const text = `
      <div style="line-height: 25px;">
        <b>车辆当前位置信息</b><br/>
        <b>车牌号： ${this.currentVehicle.license_plate_number} </b><br/>
        <b>当前经纬度： ${lon},${lat} </b><br/>
        <b>车辆位置： ${addressres.data.formatted_address} </b><br/>
        <b>车辆方向： ${this.getDirection(degree)} </b><br/>
        <b>定位类型： ${this.getLocationInfoType(this.currentVehicle.lastLocation.lastLocationInfoType)}定位</b><br/>
        <b>车辆状态： ${this.getStatus(this.currentVehicle.lastLocation.status)} </b><br/>
        <b>车辆最后定位时间： ${this.currentVehicle.lastLocation.lastLocationTime} </b><br/>
        <b>GPS最后更新时间： ${this.currentVehicle.lastLocation.lastDataTime} </b><br/>
       </div>`
      this.addRotatedCarToMap(lon, lat, degree, text)
      this.setCenterAndZoom(lon, lat, 18)
    },

    addRotatedCarToMap(lon, lat, degree, windowContent) {
      if (this.currentVehicle.marker) {
        this.map.removeOverLay(this.currentVehicle.marker)
      }

      const icon = new T.Icon({
        iconUrl: 'https://obs-user-test.obs.cn-east-3.myhuaweicloud.com:443/pictures/test_1753672404_aImt0o3Jg7.png'
      })

      const marker = new T.Marker(new T.LngLat(lon, lat), { icon })
      this.map.addOverLay(marker)
      const infoWindow = new T.InfoWindow()
      infoWindow.setContent(windowContent)
      marker.openInfoWindow(infoWindow)

      marker.addEventListener('click', () => {
        marker.openInfoWindow(infoWindow)
      })

      this.currentVehicle.marker = marker
    },

    async handleSelectVehicleChange(e) {
      this.currentVehicle = this.vehiclesList.find(item => item.id === e)
      this.clearMapOverlays()

      if (!this.currentVehicle?.imei) {
        return this.$message.error('该车辆暂未绑定GPS设备，请绑定后尝试')
      }

      const res = await newLocation({ 'id': e })
      if (!res.data[0]) {
        return this.$message.error('当前车辆暂无定位信息，请稍后重试')
      }
      this.currentVehicleLastLocation = res.data[0]

      if (!this.formHistory.time || !this.formHistory.time.length) {
        this.getVehiclesNowLocation(res.data[0])
      }
    },

    async handleTimeChange(e) {
      if (this.currentStayPosition?.marker) {
        this.cancelMarkerFlashing(this.currentStayPosition.marker)
      }
      this.stayPositionList = []

      if (!e) {
        this.clearMapOverlays()
        if (this.currentVehicleLastLocation) {
          this.getVehiclesNowLocation(this.currentVehicleLastLocation)
        } else {
          const res = await newLocation({ 'id': this.id })
          if (res.data[0]) {
            this.currentVehicleLastLocation = res.data[0]
            this.getVehiclesNowLocation(res.data[0])
          }
        }
      }
    },

    handleFocusNow() {
      if (this.formHistory.time && this.formHistory.time.length === 2 && this.currentStayPosition) {
        this.setCenterAndZoom(this.currentStayPosition.lon, this.currentStayPosition.lat, 18)
        this.startMarkerFlashing(this.currentStayPosition.marker)
      } else if (this.currentVehicleLastLocation) {
        this.setCenterAndZoom(this.currentVehicleLastLocation.lastLon, this.currentVehicleLastLocation.lastLat, 18)
        this.$message.info('已定位到车辆最新位置。')
      } else {
        this.$message.warning('当前无法定位，请先查询数据。')
      }
    }
  }
}
</script>

<style scoped lang='scss'>

.vehicle-management {
  display: flex;
  height: 90vh;
  position: relative;
}

.map-container {
  position: relative;
  transition: all 0.5s cubic-bezier(0.25, 0.8, 0.25, 1);
  will-change: width;
}
.position-icon {
  width: 60px;
  height: 60px;
  border-radius: 10px;
  position: absolute;
  right: 20px;
  bottom: 120px;
  z-index: 9999;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #fff;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  cursor: pointer;
  &__icon {
    width: 30px;
    height: 30px;
  }
}
#mapDiv {
  width: 100%;
  height: 100%;
  transition: all 0.5s ease;
}

.stay-position {
  position: absolute;
  right: 0;
  top: 0;
  background-color: #fff;
  width: 25%;
  z-index: 999;
  overflow: hidden;
  transition: all 0.5s cubic-bezier(0.25, 0.8, 0.25, 1);
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  border-radius: 15px 0 0 0;
  height: 100%;
  padding-bottom: 80px;

  &-list {
    max-height: 100%;
    overflow-y: auto;
    padding: 0 10px;
    border-radius: 4px;

    &__item {
      margin-top: 10px;
      cursor: pointer;
      &.active .el-card {
        border: 1px solid #409EFF;
      }
    }
  }
}

.title {
  padding: 0 10px;
  display: flex;
  justify-content: space-between;
  text-align: center;
  border-bottom: 1px solid #eee;
}

.collapse-btn {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 60px;
  background: #409EFF;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 4px 0 0 4px;
  z-index: 999;

  &:hover {
    background: #66b1ff;
  }
}

.sw {
  display: flex;
  justify-content: space-between;
}

.active {
  border: 1px solid #409EFF;
}

::v-deep .rotated-marker {
  z-index: 999;
  pointer-events: auto;
}

::v-deep .rotated-marker img {
  width: 100%;
  height: 100%;
  display: block;
}

.operate {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  z-index: 9999999;
  background-color: #fff;
  border-radius: 15px 0 0 0;
  padding: 10px;
  box-shadow: 0 -10px 10px rgba(0, 0, 0, 0.1);
}
</style>
